#ifndef LECTEURPHRASEAVECARBRE_H_
#define LECTEURPHRASEAVECARBRE_H_
 
#include "Symbole.h"
#include "LecteurSymbole.h"
#include "TableSymboles.h"
#include "Arbre.h"
 
#include <string>
using namespace std;
 
class LecteurPhraseAvecArbre
{
public:
    LecteurPhraseAvecArbre(string nomFich);  // Construit un lecteur de phrase pour interpreter
                                             //  le programme dans le fichier nomFich
 
    void analyse();  // Si le contenu du fichier est conforme à la grammaire,
                     //   cette méthode se termine normalement et affiche un message "Syntaxe correcte".
                         //   la table des symboles (ts) et l'arbre abstrait (arbre) auront été construits
                     // Sinon, le programme sera interrompu (exit).
 
    inline TableSymboles getTs ()    { return ts;    } // accesseur
    inline Noeud*        getArbre () { return arbre; } // accesseur
     
 
private:
    LecteurSymbole ls;    // le lecteur de symboles utilisé pour analyser le fichier
    TableSymboles  ts;    // la table des symboles valués
    Noeud*         arbre; // l'arbre abstrait
 
    // implémentation de la grammaire
    Noeud*  programme();   //   <programme> ::= debut <seqInst> fin FIN_FICHIER
    Noeud*  seqInst();     //     <seqInst> ::= <inst> ; { <inst> ; }
    Noeud*  inst();        //        <inst> ::= <affectation>
    Noeud*  affectation(); // <affectation> ::= <variable> = <expression>
    Noeud*  expression();  //  <expression> ::= <facteur> { <opBinaire> <facteur> }
    Noeud*  facteur();     //     <facteur> ::= <entier>  |  <variable>  |  - <facteur>  | non <facteur> |( <expression> )
    Noeud* terme();     //  <terme>       ::= <facteur> {<opMult> <facteur>}
    Symbole opAdd(); // <opAdd>  ::= + | -
    Symbole opMult(); // <opMult>  ::= * | /
    Noeud* expBool(); // <expBool> ::= <relation> { <opBool> <relation> }
    Symbole opBool(); //  <opBool> ::=  et | ou
    Noeud* relation(); //  <relation> ::= <expression> { <opRel> <expression>
    Symbole opRel(); //  <opRel> ::=  == | != | < | <= | > | >=
    Symbole opUnaire(); //  <opUnaire> ::= - | non
    Noeud* instSi(); //  <instSi> ::= si(<expBool>)<seqInst> {sinonsi(<expBool>)<seqInst> }
                     //  [sinon <seqInst> ]finsi
    Noeud* instTq(); //  <instTq> ::= tantque(<expBool>) <seqInst> fintantque
    Noeud* instRepeter(); // <instRepeter> ::= repeter <seqInst>jusqua(<expBool>)
    Noeud* instPour(); // <instPour> ::= pour (<affectation> <expBool> <expression>) <seqInst> finpour
   
    Noeud* instLire(); //  <instLire> ::= lire(<variable>)
    Noeud* instEcrire(); //  <instEcrire> ::= ecrire (<expression> | <chaine>)
    Noeud* instSwitch(); //	<instSwitch> ::= switch (<VARIABLE>) { case <ENTIER>: [<seqInst> break;] } [default: <seqInst> break;] endswitch
 
    // outils pour se simplifier l'analyse syntaxique
    void testerSymCour (string ch);  // si symbole courant != ch, erreur : on arrete le programme, sinon rien
    void sauterSymCour (string ch);  // si symbole courant == ch, on passe au symbole suivant, sinon erreur : on arrete
    void erreur (string mess);      // affiche les message d'erreur mess et arrete le programme
};
 
#endif /* LECTEURPHRASEAVECARBRE_H_ */